package cn.ibizlab.core.authentication.provider;

import cn.ibizlab.core.authentication.config.GlobalLdapConfig;
import cn.ibizlab.core.authentication.constants.AuthenticationConstant;
import cn.ibizlab.core.authentication.domain.AuthProvider;
import cn.ibizlab.core.authentication.service.impl.LdapAuthenticationService;
import cn.ibizlab.util.enums.Entities;
import cn.ibizlab.util.errors.BadRequestAlertException;
import com.alibaba.fastjson.JSON;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.DigestUtils;

import javax.annotation.PostConstruct;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * ldap认证服务工厂类：根据配置动态构造ldap认证服务
 */
@Component
public class LdapAuthenticationServiceFactory implements AuthenticationServiceFactory{

    @Autowired
    GlobalLdapConfig globalLdapConfig;
    @Autowired
    AuthenticationServiceManager authenticationServiceManager;
    private Map<String, LdapAuthenticationService> apiAuthenticationProviderMap = new LinkedHashMap<>();

    @PostConstruct
    public void init() {
        authenticationServiceManager.registerAuthenticationServiceFactory(this);
    }

    @Override
    public boolean supports(AuthProvider provider) {
        if (provider != null && AuthenticationConstant.PROVIDER_LDAP.equals(provider.getAuthenticationType())) {
            return true;
        }
        return false;
    }

    @Override
    public AuthenticationService getAuthenticationService(AuthProvider provider) {

        if (provider == null || !AuthenticationConstant.PROVIDER_LDAP.equals(provider.getAuthenticationType()))
            throw new BadRequestAlertException("未配置ldap认证服务", Entities.AUTH_PROVIDER.toString(), "First Ldap");

        String providerKey = DigestUtils.md5DigestAsHex(JSON.toJSONString(provider).getBytes());
        String providerId = provider.getId();

        //优先从缓存中查找之前构造过的认证服务
        LdapAuthenticationService authenticationService = apiAuthenticationProviderMap.get(providerId);
        //provider配置未发生变化时，则返回原配置的认证服务
        if (authenticationService != null && providerKey.equals(authenticationService.getId()))
            return authenticationService;

        //认证服务不存在，根据配置构建认证服务
        provider.set("defaultConfig", globalLdapConfig.getDefaultConfigMap());//设置默认的ldap配置，当认证配置中未配置ldap参数时，则使用默认配置
        authenticationService = new LdapAuthenticationService(provider);
        apiAuthenticationProviderMap.put(providerId, authenticationService);

        return authenticationService;

    }

}
